home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 2: CDPD 1 / Almathera Ten on Ten - Disc 2: CDPD 1.iso / pd / 076-100 / 084 / ed / makepat.c < prev    next >
C/C++ Source or Header  |  1995-03-13  |  3KB  |  155 lines

  1. #include <stdio.h>
  2. #include "tools.h"
  3.  
  4. /*
  5.  * Make a pattern template from the strinng pointed to by arg.  Stop
  6.  * when delim or '\000' or '\n' is found in arg.  Return a pointer to
  7.  * the pattern template.
  8.  *
  9.  * The pattern template used here are somewhat different than those
  10.  * used in the "Software Tools" book; each token is a structure of
  11.  * the form TOKEN (see tools.h).  A token consists of an identifier,
  12.  * a pointer to a string, a literal character and a pointer to another
  13.  * token.  This last is 0 if there is no subsequent token.
  14.  *
  15.  * The one strangeness here is caused (again) by CLOSURE which has
  16.  * to be put in front of the previous token.  To make this insertion a
  17.  * little easier, the 'next' field of the last to point at the chain
  18.  * (the one pointed to by 'tail) is made to point at the previous node.
  19.  * When we are finished, tail->next is set to 0.
  20.  */
  21. TOKEN *
  22. makepat(arg, delim)
  23. char    *arg;
  24. int    delim;
  25. {
  26.      TOKEN    *head, *tail, *ntok;
  27.      char    buf[CLS_SIZE];
  28.      int    error;
  29.      extern char *malloc ();
  30.  
  31.     /*
  32.      * Check for characters that aren't legal at the beginning of
  33.      * a template.
  34.      */
  35.  
  36.     if (*arg=='\0' || *arg==delim || *arg=='\n' || *arg==CLOSURE)
  37.         return(0);
  38.  
  39.     error = 0;
  40.     tail = head = NULL;
  41.  
  42.     while (*arg && *arg != delim && *arg != '\n' && !error)
  43.     {
  44.         ntok = (TOKEN *)malloc(TOKSIZE);
  45.         ntok->lchar = '\000';
  46.         ntok->next = 0;
  47.  
  48.         switch(*arg)
  49.         {
  50.         case ANY:
  51.             ntok->tok = ANY;
  52.             break;
  53.  
  54.         case BOL:
  55.             if (head == 0)    /* then this is the first symbol */
  56.                 ntok->tok = BOL;
  57.             else
  58.                 ntok->tok = LITCHAR;
  59.                 ntok->lchar = BOL;
  60.             break;
  61.  
  62.         case EOL:
  63.             if(*(arg+1) == delim || *(arg+1) == '\000' ||
  64.                     *(arg+1) == '\n')
  65.             {
  66.                 ntok->tok = EOL;
  67.             } else {
  68.                 ntok->tok = LITCHAR;
  69.                 ntok->lchar = EOL;
  70.             }
  71.             break;
  72.  
  73.         case CLOSURE:
  74.             if (head != 0)
  75.             {
  76.                 switch (tail->tok)
  77.                 {
  78.                 case BOL:
  79.                 case EOL:
  80.                 case CLOSURE:
  81.                     return (0);
  82.                 
  83.                 default:
  84.                     ntok->tok = CLOSURE;
  85.                 }
  86.             }
  87.             break;
  88.  
  89.         case CCL:
  90.  
  91.             if(*(arg + 1) == NEGATE)
  92.             {
  93.                 ntok->tok = NCCL;
  94.                 arg += 2;
  95.             } else {
  96.                 ntok->tok = CCL;
  97.                 arg++;
  98.             }
  99.  
  100.             if( ntok->bitmap = makebitmap(CLS_SIZE) )
  101.                 arg = dodash(CCLEND, arg, ntok->bitmap );
  102.             else {
  103.                 fprintf(stderr,"Not enough memory for pat\n");
  104.                 error = 1;
  105.             }
  106.             break;
  107.  
  108.         default:
  109.             ntok->tok = LITCHAR;
  110.             ntok->lchar = esc(&arg);
  111.         }
  112.  
  113.         if (error || ntok == 0)
  114.         {
  115.             unmakepat(head);
  116.             return (0);
  117.         } else if (head == 0)
  118.         {
  119.                 /* This is the first node in the chain. */
  120.             
  121.             ntok->next = 0;
  122.             head = tail = ntok;
  123.         } else if (ntok->tok != CLOSURE)
  124.         {
  125.             /* Insert at end of list (after tail) */
  126.  
  127.             tail->next = ntok;
  128.             ntok->next = tail;
  129.             tail = ntok;
  130.         } else if (head != tail)
  131.         {
  132.             /*
  133.              * More than one node in the chain.  Insert the
  134.              * CLOSURE node immediately in front of tail.
  135.              */
  136.             
  137.             (tail->next)->next = ntok;
  138.             ntok->next = tail;
  139.         } else {
  140.             /*
  141.              * Only one node in the chain,  Insert the CLOSURE
  142.              * node at the head of the linked list.
  143.              */
  144.             
  145.             ntok->next = head;
  146.             tail->next = ntok;
  147.             head = ntok;
  148.         }
  149.         arg++;
  150.     }
  151.  
  152.     tail->next = 0;
  153.     return (head);
  154. }
  155.